<template>
  <div class="note-layout" v-loading="loading">
    <div
      style="height: 100%"
      v-if="(!isLock && !loading) || (!isOwner && !loading)"
    >
      <!-- 判断是不是自己的笔记, -->
      <template v-if="isOwner || (!isOwner && noteDetail.set)">
        <div class="note-content">
          <el-breadcrumb separator-icon="ArrowRight">
            <el-breadcrumb-item :to="{ path: '/file/share' }">
              <div style="display: flex; align-items: center">
                <el-icon class="no-inherit">
                  <Share />
                </el-icon>
                分享
              </div>
            </el-breadcrumb-item>
            <el-breadcrumb-item> {{ noteDetail.title }} </el-breadcrumb-item>
          </el-breadcrumb>
          <div class="right">
            <MoreOperation
              :data="noteDetail"
              :lock="isLock"
              :initLock="initLock"
              @update="updateNote"
            />
          </div>
        </div>
        <template v-if="pageType === 'Xmind'">
          <el-input
            class="title-input"
            v-model="title"
            @input="handleUpdateTitle"
            placeholder="请输入标题"
          />
          <div class="mind-map">
            <MindMap
              ref="mindMapRef"
              :data="data.content"
              @change="handleChange"
              :readonly="!hasPermission"
            />
          </div>
        </template>
        <div class="document" v-else-if="pageType === 'Document'">
          <Document
            :disabled="!hasPermission"
            v-model:title="title"
            @onSave="handleSave"
            :initTitle="noteDetail.title"
            :content="content"
          />
        </div>
        <template v-else-if="pageType === 'FlowChart'">
          <el-input
            class="title-input"
            v-model="title"
            @input="handleUpdateTitle"
            placeholder="请输入标题"
          />
          <diagram
            :data="content"
            :isSilentMode="!hasPermission"
            @saveGraph="handleChange"
          />
        </template>
      </template>
      <!-- 无效链接 -->
      <div class="invalid-wrapper" v-else>
        <div>
          <el-icon size="128" color="#537def"><Warning /></el-icon>
          <p>无效分享地址</p>
          <p style="color: #7f7f7f">对方停止分享或该分享不存在</p>
        </div>
      </div>
    </div>
    <NoteLock
      v-else-if="!loading && isLock && isOwner"
      :data="noteDetail"
      @unlock="handleUnlock"
      @update="updateNote"
    ></NoteLock>
  </div>
</template>
<script setup>
import { reactive, ref, watch, provide } from 'vue'
import { debounce, removeFieldFromTree } from '@/utils/tools.ts'
import BreadCrumb from './components/BreadCrumb.vue'
import { useRoute } from 'vue-router'
import {
  httpCreateNoteRelation,
  httpDeleteNoteRelation,
  httpGetNoteDetail,
  httpUpdateNote,
} from '@/api/note'
import MindMap from '@/components/mind-map/Index.vue'
import Document from './components/document.vue'
import Diagram from '@/components/logic-flow-mvp/components/Diagram.vue'
import MoreOperation from './components/MoreOperation.vue'
import NoteLock from './components/NoteLock.vue'
import { jsonToObject } from '@/utils/index.js'
import { ElMessage } from 'element-plus'
import useNoteStore from '@/stores/note'
import useUserStore from '@/stores/user.js'
import { storeToRefs } from 'pinia'
const noteState = useNoteStore()
const userStore = useUserStore()
const { info } = storeToRefs(userStore)
const route = useRoute()
const loading = ref(true)
const title = ref('')
const noteDetail = ref({}) // 当前笔记所有信息
const breadcrumbList = ref([])
const editId = ref()
const isLock = ref(false)
const initLock = ref(false)
const associations = ref([])
const pageType = ref('')
const labels = ref([])
// ========================================================== xmind
const data = reactive({
  content: {
    data: {
      text: '根节点',
    },
    children: [],
  },
})
const mindMapRef = ref()
const mmChangeData = ref()
// ========================================================== xmind
// ========================================================== doc start
const noteTitle = ref()
const content = ref('') // xmind flowchart
// ========================================================== doc end
const handleUnlock = () => {
  isLock.value = false
}
const updateNote = () => {
  getNoteDetail()
}
const updateBreadcrumb = async () => {
  const res = await httpGetNoteDetail({
    fd_id: route.params.id,
  })
  const { list } = res
  if (list.length) {
    const { crumb } = list[0]
    let arr = crumb.reverse()
    arr[0] && arr[0].parent_id === 0 && (arr[0].name = '全部笔记')
    breadcrumbList.value = arr
    noteDetail.value = list[0]
  }
}
provide('updateBreadcrumb', updateBreadcrumb)

const hasPermission = ref(false) // 是否有权限进行编辑
const isOwner = ref(false)

const getNoteDetail = async () => {
  loading.value = true
  const res = await httpGetNoteDetail({
    fd_id: route.params.id,
  })
  const { list } = res
  if (list.length) {
    const firstItem = list[0]
    const { is_lockbox, crumb } = firstItem
    // const { is_lockbox, crumb } = list[0]
    noteDetail.value = firstItem
    noteTitle.value = firstItem.title
    title.value = firstItem.title
    editId.value = firstItem.id
    isLock.value = !!is_lockbox
    initLock.value = !!is_lockbox
    pageType.value = firstItem.icon
    labels.value = firstItem.label?.map((x) => x.label_id)
    // 判断是不是自己的笔记
    if (info.value.user_info_id === firstItem.user_info_id) {
      hasPermission.value = true
      isOwner.value = true
    } else {
      // 不是自己的笔记，判断是不是有权限编辑
      hasPermission.value = firstItem.set && firstItem.set.authority == 1
      isOwner.value = false
    }

    let arr = crumb.reverse()
    arr[0] && arr[0].parent_id === 0 && (arr[0].name = '全部笔记')
    breadcrumbList.value = arr
    if (firstItem.icon === 'Xmind') {
      // ximnd
      data.content = firstItem.content
        ? JSON.parse(firstItem.content)
        : {
            data: {
              text: '根节点',
            },
            children: [],
          }

      associations.value = getContentAssociationsXmind(data.content)
    } else if (firstItem.icon === 'Document') {
      // doc
      content.value = firstItem.content
      associations.value = getContentAssociations(firstItem.content)
    } else if (firstItem.icon === 'FlowChart') {
      //FlowChart
      content.value = firstItem.content
        ? JSON.parse(firstItem.content)
        : { nodes: [], edges: [] }
      associations.value = getContentAssociationsFlowChart(content.value)
    }
  }
  loading.value = false
}
const handleUpdateTitle = debounce(async () => {
  let content
  if (pageType.value === 'Xmind') {
    content = mmChangeData.value
      ? JSON.stringify(mmChangeData.value)
      : JSON.stringify(data.content)
  } else if (pageType.value === 'FlowChart') {
    content = JSON.stringify(content.value)
  }
  await httpUpdateNote({
    fd_id: editId.value,
    title: title.value,
    content,
    label_id_list: labels.value,
  })
}, 300)
// xmind flowchart
const handleChange = async (value) => {
  let data = value
  if (pageType.value == 'Xmind') {
    data = removeFieldFromTree([value], '_node')[0]
    mmChangeData.value = data
  }
  await httpUpdateNote({
    fd_id: editId.value,
    title: title.value,
    content: JSON.stringify(data),
    label_id_list: labels.value,
  })
  updateAssociations(value)
}

// doc
const handleSave = async (value) => {
  let data = {
    fd_id: editId.value,
    content: value,
    label_id_list: labels.value,
    title: title.value.trim() ? title.value : noteDetail.value.title,
  }
  const res = await httpUpdateNote(data).catch(() => null)
  if (res) {
    if (data.title !== noteTitle.value) {
      noteTitle.value = data.title
      await noteState.getFolderListData()
    }
    // await getNoteDetail(route.params.docId)
    content.value = value
    updateAssociations(value)
  } else {
    ElMessage.error('更新失败')
  }
}
const getContentAssociationsXmind = (contentValue) => {
  let associationsArr = []
  const { data, children } = contentValue
  if (children && children.length) {
    children.forEach((child) => {
      associationsArr = associationsArr.concat(
        getContentAssociationsXmind(child),
      )
    })
  }
  const { hyperlinkTitle } = data
  if (hyperlinkTitle) {
    const hyperlinkTitleObj = jsonToObject(hyperlinkTitle)
    if (hyperlinkTitleObj && hyperlinkTitleObj.id) {
      associationsArr.push(hyperlinkTitleObj.id)
    }
  }
  return associationsArr
}

const updateAssociations = (result) => {
  let arr
  if (pageType.value == 'Xmind') {
    arr = getContentAssociationsXmind(result)
  } else if (pageType.value == 'Document') {
    arr = getContentAssociations(result)
  } else if (pageType.value == 'FlowChart') {
    arr = getContentAssociationsFlowChart(result)
  }
  if (arr.sort().join() !== associations.value.sort().join()) {
    arr.forEach((id1) => {
      if (associations.value.indexOf(id1) < 0) {
        httpCreateNoteRelation({
          source_id: route.params.id,
          target_id: id1,
        }).catch(() => null)
      }
    })
    associations.value.forEach((id2) => {
      if (arr.indexOf(id2) < 0) {
        httpDeleteNoteRelation({
          source_id: route.params.id,
          target_id: id2,
        }).catch(() => null)
      }
    })
    associations.value = arr
  }
}
const getContentAssociations = (content) => {
  // 正则表达式匹配<a>标签中的href属性
  const regex = /<a[^>]*href="([^"]*)"[^>]*>/g
  // 匹配所有符合条件的链接
  const ids = []
  let match
  const includes = ['/file/doc/', '/file/mindmap/', '/file/drawio/']
  while ((match = regex.exec(content)) !== null) {
    let str = match[1]
    if (str) {
      includes.forEach((include) => {
        if (str.includes(include)) {
          str = str.endsWith('/') ? str.substring(0, str.length - 1) : str
          const id = parseInt(str.split(include)[1].split('?')[0])
          if (!isNaN(id) && id > 0) {
            ids.push(id)
          }
        }
      })
    }
  }
  return ids
}
const getContentAssociationsFlowChart = (contentValue) => {
  const associationsArr = []
  const { nodes } = contentValue
  nodes.forEach((node) => {
    if (node.properties && node.properties.linkId) {
      const idArr = node.properties.linkId.split('-')
      const id = parseInt(idArr[1])
      if (!isNaN(id) && id > 0) {
        associationsArr.push(id)
      }
    }
  })
  return associationsArr
}
watch(
  () => route.params.id,
  () => {
    getNoteDetail()
  },
  {
    immediate: true,
  },
)
</script>
<style scoped lang="scss">
.mind-map {
  height: calc(100vh - 103px);
  width: 100%;
}

.title-input {
  background: rgb(250, 250, 250);

  :deep(.el-input__wrapper) {
    background-color: #fafafa;
    box-shadow: none !important;
    font-size: 18px;
    color: #000;
    font-weight: 600;
  }

  ::-webkit-input-placeholder {
    font-size: 14px;
  }

  :-moz-placeholder {
    font-size: 14px;
  }

  :-ms-input-placeholder {
    font-size: 14px;
  }

  :deep(.el-input__inner) {
    color: #000;
  }
}

.note-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
}
.document {
  height: calc(100vh - 40px);
}
.note-layout {
  height: 100%;
  // display: flex;
  // justify-content: center;
  // align-items: center;
  // padding: 100px 0;
}
.invalid-wrapper {
  margin: 0 auto;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
